//
//  RichTableViewController.m
//  Rich
//
//  Created by Kenny Chen on 13/8/17.
//  Copyright (c) 2013年 Kenny Chen. All rights reserved.
//

#import "RichUI.h"
#import "RichTableViewController.h"

@interface RichTableViewController ()

@end

@implementation RichTableViewController

@synthesize navigator;
@synthesize callerDelegate;
@synthesize mode;
@synthesize page;
@synthesize listSection;
@synthesize rowsNotAllowEditing;

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        mode = RichTableModeListEditable;
        tableCellStyle = RichTableCellStyleDefault;
        callerDelegate = nil;
        page = 0;
        listSection = 0;
        rowsNotAllowEditing = 0;
        defaultPickerTitles = nil;
        
        accounts = [[NSMutableArray alloc] init];
    }
    return self;
}

- (void)initDatePicker
{
    datePicker = [[FormatableDatePicker alloc] init];
    datePicker.timeZone = [NSTimeZone timeZoneWithName:@"Asia/Taipei"]; // FIXME: [DatePicker] Handling different time zone
    datePicker.date = [NSDate date];
}

- (void)initDefaultPicker
{
    defaultPicker = [[UIPickerView alloc] init];
    defaultPicker.showsSelectionIndicator = YES;
    defaultPicker.delegate = self;
    defaultPicker.dataSource = self;
    defaultPicker.tag = RichPickerIdDefault;
}

- (void)initAccountTypePicker
{
    accountTypePicker = [[UIPickerView alloc] init];
    accountTypePicker.showsSelectionIndicator = YES;
    accountTypePicker.delegate = self;
    accountTypePicker.dataSource = self;
    accountTypePicker.tag = RichPickerIdAccountType;
    
    accountTypes = [[NSMutableArray alloc] init];
    currentTextfield = nil;
    
    for (int i = 0; i < AccountTypeVisibleEnd; i++)
        if ([[RichDelegate core] accountTypeToString:i])
            [accountTypes addObject:[[RichDelegate core] accountTypeToString:i]];
}

- (void)initAccountPropertyPicker
{
    accountPropertyPicker = [[UIPickerView alloc] init];
    accountPropertyPicker.showsSelectionIndicator = YES;
    accountPropertyPicker.delegate = self;
    accountPropertyPicker.dataSource = self;
    accountPropertyPicker.tag = RichPickerIdAccountProperty;
}

- (void)initCurrencyPicker
{
    currencyPicker = [[UIPickerView alloc] init];
    currencyPicker.showsSelectionIndicator = YES;
    currencyPicker.delegate = self;
    currencyPicker.dataSource = self;
    currencyPicker.tag = RichPickerIdCurrency;
}

- (void)initTransPropertyPicker:(RootCategory)category;
{
    transPropertyPicker = [[UIPickerView alloc] init];
    transPropertyPicker.showsSelectionIndicator = YES;
    transPropertyPicker.delegate = self;
    transPropertyPicker.dataSource = self;
    transPropertyPicker.tag = RichPickerIdTransProperty;
    transPropCategory = category;
}

- (void)initInstallmentPeriodPicker
{
    installmentPeriodPicker = [[UIPickerView alloc] init];
    installmentPeriodPicker.showsSelectionIndicator = YES;
    installmentPeriodPicker.delegate = self;
    installmentPeriodPicker.dataSource = self;
    installmentPeriodPicker.tag = RichPickerIdInstallmentPeriod;
}

- (void)initBarButtonItems
{
    barDoneButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
                                                                      target:self
                                                                      action:@selector(navBarDidPressDoneButton:)];
    barEditButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit
                                                                      target:self
                                                                      action:@selector(navBarDidPressEditButton:)];
}

- (void)initInputToolbar:(NSUInteger)buttons
{
    NSMutableArray *items = [[NSMutableArray alloc] init];
    inputToolbar = [[UIToolbar alloc] init];
    inputToolbar.barStyle = UIBarStyleBlackTranslucent;
    [inputToolbar sizeToFit];
    
    if (buttons & RichInputToolbarButtonBack) {
        toolbarBackButtonItem = [[UIBarButtonItem alloc] initWithTitle:RichLocaleString(@"Back")
                                                                 style:UIBarButtonItemStyleBordered
                                                                target:self
                                                                action:@selector(toolbarDidPressBackButton:)];
        [items addObject:toolbarBackButtonItem];
    }
    
    toolbarFlexibleSpaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
                                                                             target:nil
                                                                             action:nil];
    [items addObject:toolbarFlexibleSpaceItem];
    
    if (buttons & RichInputToolbarButtonNext) {
        toolbarNextButtonItem = [[UIBarButtonItem alloc] initWithTitle:RichLocaleString(@"Next")
                                                                 style:UIBarButtonItemStyleBordered
                                                                target:self
                                                                action:@selector(toolbarDidPressNextButton:)];
        [items addObject:toolbarNextButtonItem];
    }
    
    if (buttons & RichInputToolbarButtonDone) {
        toolbarDoneButtonItem = [[UIBarButtonItem alloc] initWithTitle:RichLocaleString(@"Done")
                                                                 style:UIBarButtonItemStyleDone
                                                                target:self
                                                                action:@selector(toolbarDidPressDoneButton:)];
        [items addObject:toolbarDoneButtonItem];
    }
    
    [inputToolbar setItems:items];
    [items release];
}

- (UIBarButtonItem *)barDoneButtonItem
{
    return barDoneButtonItem;
}

- (UIBarButtonItem *)barEditButtonItem
{
    return barEditButtonItem;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;
 
    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
    
    [self initBarButtonItems];
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    
    [[RichDelegate core] accounts:accounts loadWithType:AccountTypeAll];
    [[RichDelegate core] loadCategories];
    
    if (mode == RichTableModeListEditable) {
        if ([self tableView:self.tableView numberOfRowsInSection:listSection] == rowsNotAllowEditing)
            self.navigationItem.rightBarButtonItem = nil;
        else
            self.navigationItem.rightBarButtonItem = barEditButtonItem;
    }
    else if (mode == RichTableModeListReadonly)
        self.navigationItem.rightBarButtonItem = nil;
    else if (mode == RichTableModeCreate)
        self.navigationItem.rightBarButtonItem = barDoneButtonItem;
    else if (mode == RichTableModeUpdate)
        self.navigationItem.rightBarButtonItem = barDoneButtonItem;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
    [super setEditing:editing animated:animated];
    [self.tableView setEditing:editing animated:animated];
    // Reload table to hide/show header
    [self.tableView performSelector:@selector(reloadData) withObject:nil afterDelay:0.3f];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 1;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
{
    if (mode == RichTableModeListEditable) {
        if (self.isEditing)
            return 0;
        
        if (section == 0)
            return 50;
        else
            return 20;
    }
    else
        return 0;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    if (mode != RichTableModeListEditable)
        return nil;
    
    if (section == 0) {
        UIButton *createButton = [[UIButton alloc] initWithFrame:CGRectMake(tableView.center.x - 20, 5, 40, 40)];
        [createButton setBackgroundColor:[UIColor redColor]];
        [createButton setAlpha:0.8f];
        [createButton setTitle:RichLocaleString(@"┼") forState:UIControlStateNormal];
        [createButton addTarget:self action:@selector(tableViewDidPressCreateButton:) forControlEvents:UIControlEventTouchUpInside];
    
        UIView *headerView = [[UIView alloc] init];
        [headerView addSubview:createButton];
        headerView.backgroundColor = [UIColor lightGrayColor];
        [headerView setAlpha:0.5f];
        return [headerView autorelease];
    }
    else {
        UIView *headerView = [[UIView alloc] init];
        headerView.backgroundColor = [UIColor lightGrayColor];
        return [headerView autorelease];
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = nil;
    static NSString *TextfieldCellIdentifier = @"TextfieldCell";
    static NSString *ButtonCellIdentifier = @"ButtonCell";
    static NSString *ValueCellIdentifier = @"ValueCell";
    static NSString *MessageCellIdentifier = @"MessageCell";
    static NSString *DefaultCellIdentifier = @"DefaultCell";
    RichTableViewTextfieldCell *textfieldCell;
    
    switch (tableCellStyle) {
        case RichTableCellStyleTextfield:
            textfieldCell = [tableView dequeueReusableCellWithIdentifier:TextfieldCellIdentifier];
            
            if (textfieldCell == nil) {
                textfieldCell = [[[RichTableViewTextfieldCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:TextfieldCellIdentifier] autorelease];
            }
            
            textfieldCell.selectionStyle = UITableViewCellSelectionStyleNone;
            textfieldCell.textLabel.font = [UIFont boldSystemFontOfSize:14];
            textfieldCell.textfield.delegate = self;
            textfieldCell.textfield.adjustsFontSizeToFitWidth = YES;
            textfieldCell.textfield.textColor = [UIColor blackColor];
            textfieldCell.textfield.textAlignment = UITextAlignmentRight;
            textfieldCell.textfield.keyboardType = UIKeyboardTypeDefault;
            textfieldCell.textfield.returnKeyType = UIReturnKeyDone;
            textfieldCell.textfield.autocorrectionType = UITextAutocorrectionTypeYes;
            textfieldCell.textfield.autocapitalizationType = UITextAutocapitalizationTypeWords;
            textfieldCell.textfield.text = @"";
            textfieldCell.textfield.tag = [indexPath row] | ([indexPath section] << 16);
            textfieldCell.textfield.inputAccessoryView = inputToolbar;
            textfieldCell.textfield.inputView = nil;
            textfieldCell.userInteractionEnabled = YES;
            
            return (UITableViewCell *)textfieldCell;
        
        case RichTableCellStyleValue:
            cell = [tableView dequeueReusableCellWithIdentifier:ValueCellIdentifier];
            
            if (cell == nil) {
                cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:ValueCellIdentifier] autorelease];
            }
            
            cell.textLabel.font = [UIFont boldSystemFontOfSize:14];
            cell.selectionStyle = UITableViewCellSelectionStyleBlue;
            cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
            cell.userInteractionEnabled = YES;
            
            return cell;
        
        case RichTableCellStyleDetail:
            cell = [tableView dequeueReusableCellWithIdentifier:ValueCellIdentifier];
            
            if (cell == nil) {
                cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ValueCellIdentifier] autorelease];
            }
            
            cell.textLabel.font = [UIFont boldSystemFontOfSize:14];
            cell.selectionStyle = UITableViewCellSelectionStyleBlue;
            cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
            cell.userInteractionEnabled = YES;
            
            return cell;
        
        case RichTableCellStyleButton:
            cell = [tableView dequeueReusableCellWithIdentifier:ButtonCellIdentifier];
            
            if (cell == nil) {
                cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ButtonCellIdentifier] autorelease];
            }
            
            cell.textLabel.font = [UIFont boldSystemFontOfSize:16];
            cell.textLabel.textAlignment = UITextAlignmentCenter;
            cell.selectionStyle = UITableViewCellSelectionStyleBlue;
            cell.textLabel.frame = cell.frame;
            cell.userInteractionEnabled = YES;
            
            return cell;
        
        case RichTableCellStyleMessage:
            cell = [tableView dequeueReusableCellWithIdentifier:MessageCellIdentifier];
            
            if (cell == nil)
                cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MessageCellIdentifier] autorelease];
            
            cell.textLabel.textAlignment = UITextAlignmentCenter;
            cell.textLabel.font = [UIFont boldSystemFontOfSize:16];
            cell.textLabel.textColor = [UIColor darkGrayColor];
            cell.textLabel.frame = cell.frame;
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
            cell.userInteractionEnabled = YES;
            
            return cell;
            
        case RichTableCellStyleDefault:
        default:
            cell = [tableView dequeueReusableCellWithIdentifier:DefaultCellIdentifier];
            
            if (cell == nil) {
                cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:DefaultCellIdentifier] autorelease];
            }
            
            cell.textLabel.font = [UIFont boldSystemFontOfSize:14];
            cell.detailTextLabel.textColor = [UIColor blackColor];
            cell.selectionStyle = UITableViewCellSelectionStyleBlue;
            cell.accessoryType = UITableViewCellAccessoryNone;
            cell.userInteractionEnabled = YES;
            
            return cell;
    }
}

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (self.mode == RichTableModeListEditable)
        return YES;
    else
        return NO;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        if (mode == RichTableModeListEditable) {
            if ([self tableView:self.tableView numberOfRowsInSection:listSection] <= rowsNotAllowEditing) {
                self.navigationItem.rightBarButtonItem = nil;
                [self setEditing:NO];
            }
            else
                self.navigationItem.rightBarButtonItem = barEditButtonItem;
        }
    }   
    else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }   
}

/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/

/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Navigation logic may go here. Create and push another view controller.
    /*
     <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
     // ...
     // Pass the selected object to the new view controller.
     [self.navigationController pushViewController:detailViewController animated:YES];
     [detailViewController release];
     */
}

#pragma mark - Table create button actions

- (void)tableViewDidPressCreateButton:(UIButton *)sender
{
    [self.delegate didPressCreate];
}

#pragma mark - Navigation bar button actions

- (void)navBarDidPressDoneButton:(UIBarButtonItem *)sender
{
    [currentTextfield resignFirstResponder];
    
    if (self.mode == RichTableModeListEditable) {
        // Begin of showing table view header animation
        [self.tableView beginUpdates];
        
        [self setEditing:NO animated:YES];
        self.navigationItem.rightBarButtonItem = barEditButtonItem;
        
        // End of showing table view header animation
        [self.tableView endUpdates];
    }
    else if (self.mode == RichTableModeCreate) {
        [self.delegate didPressCreateDone];
    }
    else if (self.mode == RichTableModeUpdate) {
        [self.delegate didPressUpdateDone];
    }
}

- (void)navBarDidPressEditButton:(UIBarButtonItem *)sender
{
    // Begin of hiding table view header animation
    [self.tableView beginUpdates];
    
    [self setEditing:YES animated:YES];
    self.navigationItem.rightBarButtonItem = barDoneButtonItem;

    // End of hiding table view header animation
    [self.tableView endUpdates];
}

#pragma mark - Toolbar button actions

- (void)toolbarDidPressBackButton:(UIBarButtonItem *)sender
{
    
}

- (void)toolbarDidPressNextButton:(UIBarButtonItem *)sender
{
    [self textFieldShouldReturn:currentTextfield];
}

- (void)toolbarDidPressDoneButton:(UIBarButtonItem *)sender
{
    //self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
    //[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:currentTextfield.tag inSection:0]
    //                      atScrollPosition:UITableViewScrollPositionBottom animated:YES];
    
    [currentTextfield resignFirstResponder];
}

#pragma mark - Picker view delegate and datasource

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    return 1;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)tableComponents
{
    switch (pickerView.tag) {
        case RichPickerIdDefault:
            return [defaultPickerTitles count];
            
        case RichPickerIdAccountType:
            return [accountTypes count];
        
        case RichPickerIdAccountProperty:
            return AccountPropertyEnd;
        
        case RichPickerIdCurrency:
            return [[[RichDelegate core] currencies] count];
        
        case RichPickerIdTransProperty:
            if (transPropCategory == RootCategoryExpend)
                return 3;
            else if (transPropCategory == RootCategoryIncome)
                return 3;
            else if (transPropCategory == RootCategoryTransfer)
                return 1;
            else
                return 1;
        
        case RichPickerIdInstallmentPeriod:
            return TransactionInstallmentPeriodEnd;
    }
    
    return 0;
}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)tableComponents
{
    if (pickerView.tag == RichPickerIdDefault) {
        return [defaultPickerTitles objectAtIndex:row];
    }
    else if (pickerView.tag == RichPickerIdAccountType) {
        return [accountTypes objectAtIndex:row];
    }
    else if (pickerView.tag == RichPickerIdAccountProperty) {
        if (row == 0)
            return [[RichDelegate core] accountPropertyToString:(AccountProperty)row];
        else
            return [[RichDelegate core] accountPropertyToString:(1 << (row - 1))];
    }
    else if (pickerView.tag == RichPickerIdCurrency) {
        NSArray *currKeys = [[[RichDelegate core] currencies] allKeys];
        NSString *currKey = [currKeys objectAtIndex:row];
        
        return [NSString stringWithFormat:@"%@ (%@)", currKey, ((RichCurrency *)[[[RichDelegate core] currencies] objectForKey:currKey]).name];
    }
    else if (pickerView.tag == RichPickerIdTransProperty) {
        if (transPropCategory == RootCategoryExpend)
            return [[RichDelegate core] stringFromTransactionProperty:row + TransactionPropertyExpendNone];
        else if (transPropCategory == RootCategoryIncome)
            return [[RichDelegate core] stringFromTransactionProperty:row + TransactionPropertyIncomeNone];
        else
            return [[RichDelegate core] stringFromTransactionProperty:row + TransactionPropertyTransferNone];
    }
    else if (pickerView.tag == RichPickerIdInstallmentPeriod) {
        if (row == 0)
            return [[RichDelegate core] stringFromInstallmentPeriod:TransactionInstallmentPeriodMonthly];
        else if (row == 1)
            return [[RichDelegate core] stringFromInstallmentPeriod:TransactionInstallmentPeriodQuarterly];
        else if (row == 2)
            return [[RichDelegate core] stringFromInstallmentPeriod:TransactionInstallmentPeriodSemiannual];
        else
            return [[RichDelegate core] stringFromInstallmentPeriod:TransactionInstallmentPeriodAnnual];
    }
    
    return nil;
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)tableComponents
{
    if (pickerView.tag == RichPickerIdDefault)
        currentTextfield.text = [defaultPickerTitles objectAtIndex:row];
    else if (pickerView.tag == RichPickerIdAccountType)
        currentTextfield.text = [accountTypes objectAtIndex:row];
    else if (pickerView.tag == RichPickerIdAccountProperty)
        currentTextfield.text = [[RichDelegate core] accountPropertyToString:(AccountProperty)row];
    else if (pickerView.tag == RichPickerIdCurrency)
        currentTextfield.text = [[[[RichDelegate core] currencies] allKeys] objectAtIndex:row];
    else if (pickerView.tag == RichPickerIdTransProperty) {
        if (row == 0)
            currentTextfield.text = [[RichDelegate core] stringFromTransactionProperty:row];
        if (transPropCategory == RootCategoryExpend)
            currentTextfield.text = [[RichDelegate core] stringFromTransactionProperty:row];
        else if (transPropCategory == RootCategoryIncome)
            currentTextfield.text = [[RichDelegate core] stringFromTransactionProperty:row + 100];
        else if (transPropCategory == RootCategoryTransfer)
            currentTextfield.text = [[RichDelegate core] stringFromTransactionProperty:row + 200];
    }
    else if (pickerView.tag == RichPickerIdInstallmentPeriod)
        currentTextfield.text = [[RichDelegate core] stringFromInstallmentPeriod:row + 1];
}

#pragma mark - Textfield delegate

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    [textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
    currentTextfield = textField;
}

- (void)textFieldDidChange:(UITextField *)textField
{
    return;
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    [textField removeTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    UITableViewCell *nextCell;
    NSUInteger row = textField.tag & 0x0000ffff;
    NSUInteger section = textField.tag >> 16;
    
    if (textField.returnKeyType == UIReturnKeyDone) {
        if (textField.tag >= 0)
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:section]
                                  atScrollPosition:UITableViewScrollPositionBottom animated:YES];
        [textField resignFirstResponder];
    }
    else if (textField.returnKeyType == UIReturnKeyNext) {
        do {
            // Ignore if cell is not Textfield style
            nextCell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:++row inSection:section]];
        } while (nextCell && ![nextCell respondsToSelector:@selector(setTextfield:)]);
        
        if (nextCell) {
            [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:section]
                                  atScrollPosition:UITableViewScrollPositionBottom animated:YES];
            [[nextCell viewWithTag:row] becomeFirstResponder];
        }
    }
    
    return YES;
}

@end
